import { _decorator, Component, find, Game, instantiate, Node, Prefab, resources, tween, v3 } from 'cc';
import { CardPath, cardPatternsType, colorType, effectType, GameData } from '../GameData';
import { Card } from './Card';
import { ModuleBase } from './ModuleBase';
import { CardDeck } from './CardDeck';
import { Cards } from './Cards';
import { ModuleMgr } from './ModuleMgr';
import { PlayNumAndDisNum } from '../Function/PlayNumAndDisNum';
import { JokerMgr } from '../Function/JokerMgr';
import { JokerEffectData } from './EffectBase';
import { UIMgr } from '../UIMgr';
import { Emitter } from '../Emitter';
const { ccclass, property } = _decorator;

@ccclass('CardMgr')
export class CardMgr extends ModuleBase {
    //抽牌堆
    private cards:Card[]=[];
    get _cards(){
        return this.cards;
    }
    private cardnum:number=52;
    get _cardnum(){
        return this.cardnum
    }
    @property({type:Prefab, displayName:'Card'})
    card:Prefab=null;
    //弃牌堆
    private upCards:Card[]=[];
    //出牌数组
    private useCard:Card[]=[];
    //牌型
    private cardPair:string='';
    init(){               //生成初始牌组
        for (let i = 0; i <= 3; i++) {
            for (let j = 2; j <= (this.cardnum / 4)+1; j++) {
                this.AddCard(j, i);
                //console.log("生成卡牌:" + j + " " + colorType[i]);
            }
        }       
    }
    addnewCard(card:Card){
        this.cards.push(card);
        let carddeck = this.node.parent.getChildByName("CardDeck");
        card.node.parent = carddeck;
        card.node.active = false;
        //console.log(this.cards.length);
        //改变牌堆卡牌计数数
        this.cardnum++;     
    }
    //将手牌置顶
    topCard(upLayer:Node){
        let handCard=this.node.parent.getChildByName("Cards");
        handCard.parent=upLayer;
        return handCard;
    }
    //重启
    reStart(){
        //将手牌放入抽牌堆
        let card=[];
        for(let i=0;i<this.node.parent.getChildByName("Cards").children.length;i++){
            let ts=this.node.parent.getChildByName("Cards").children[i].getComponent(Card);
            card.push(ts);
        }
        for(let i=0;i<card.length;i++){
            this.cards.push(card[i]);
            card[i].node.active = false;
            card[i].node.parent = this.node.parent.getChildByName("CardDeck");
            card[i].node.setPosition(0, 0); // 移回牌堆
        }
        //将弃牌堆重新放入抽牌堆中
        for(let i=0;i<this.upCards.length;i++){
            this.cards.push(this.upCards[i]);
        }
        //清空手牌
        this.node.parent.getChildByName("Cards").getComponent(Cards).handCard=[];
        //清空弃牌堆
        this.upCards=[];
        //重新打乱
        this.shakeout();
        //将所有istouch全部为false
        for(let i=0;i<this.cards.length;i++){
            this.cards[i].getComponent(Card).istouch=false;
        }
        //重新抽牌
        //console.log(this.cards.length);
        let cardsNum=ModuleMgr.instance.getModuel<CardDeck>("CardDeck").Cardnum;
        this.DrawCard(cardsNum);
        
    }
    //整理牌
    SortCard(handCard:Card[]){
        const n = handCard.length;
        let pos:number[]=[];
        //存储牌位置
        for(let i=0;i<=handCard.length-1;i++){
            pos.push(handCard[i].node.x);
        }
        // 外层循环：控制排序的轮数（需要 n-1 轮）
        for (let i = 0; i < n - 1; i++) {
            // 内层循环：每轮比较相邻元素
            for (let j = 0; j < n - 1 - i; j++) {
                // 如果前一个元素大于后一个元素，则交换它们
                if (handCard[j].point > handCard[j + 1].point) {
                    //[handCard[j].node.x, handCard[j + 1].node.x] = [handCard[j + 1].node.x, handCard[j].node.x];
                    [handCard[j], handCard[j + 1]] = [handCard[j + 1], handCard[j]];
                }
            }
        }
        //交换位置
        for (let i = 0; i <= handCard.length - 1; i++) {
            tween(handCard[i].node)
            .to(0.2,{x:pos[i]})
            .start();
        }
        //根据洗牌后位置更改节点优先级
        for(let i=0;i<=handCard.length-1;i++){
            handCard[i].node.setSiblingIndex(i);
        }

    }
    //计分
    score(useCard:Card[]){
        //根据排序排序
        const n = useCard.length;
        for (let i = 0; i < n - 1; i++) {
            // 内层循环：每轮比较相邻元素
            for (let j = 0; j < n - 1 - i; j++) {
                // 如果前一个元素大于后一个元素，则交换它们
                if (useCard[j].point > useCard[j + 1].point) {                    
                    [useCard[j], useCard[j + 1]] = [useCard[j + 1], useCard[j]];
                }
            }
        }
        //计算点数和
        let point=0;
        for(let i=0;i<=useCard.length-1;i++){
            point+=useCard[i].point;
        }
        //判断牌型
        let multiples=this.judgeCardByPair(useCard);
        //计算小丑牌效果
        const effectData: JokerEffectData = {
            multiplier: multiples,
            chipnum:point
        };
        this.SendMsg("callCard","JokerMgr",effectData);
        multiples=effectData.multiplier;
        point=effectData.chipnum;
        //传入计分栏
        let score=multiples*point;
        this.SendMsg("modifyScore","Score",score);
        this.SendMsg("remindCardPair","Score",this.cardPair);
        console.log(score);
    }
    //总判断牌型
    judgeCardByPair(useCard:Card[]){
        let maxnum=0;
        let num=0;
        //一对 三条 四条 五条
        for(let i=0;i<=useCard.length-1;i++){
            for (let j = 0; j <= useCard.length - 1; j++) {
                if(useCard[i].point==useCard[j].point){
                    num++;
                }
            }
            if(num>maxnum){
                maxnum=num;
            }
            num=0;
        }
        //两对 葫芦
        let pairnum=0;
        if(maxnum==2&&useCard.length>=4){
            for (let i = 0; i <= useCard.length - 1; i++) {
                for (let j = i+1; j <= useCard.length - 1; j++) {
                    if(useCard[i].point==useCard[j].point){
                        pairnum++;
                    }
                }
            }
            if(pairnum==2){
                maxnum=9;
            }
        }
        if(maxnum==3&&useCard.length==5){
            for (let i = 0; i <= useCard.length - 1; i++) {
                for (let j = i + 1; j <= useCard.length - 1; j++) {
                    if (useCard[i].point == useCard[j].point) {
                        pairnum++;
                    }
                }
            }
            if (pairnum == 4) {
                maxnum = 10;
            }
        }
        //同花
        let maxcolornum=0;
       for(let i=0;i<=useCard.length-1;i++){
            for (let j = 0; j <= useCard.length - 1; j++) {
                if(useCard[i].color==useCard[j].color){
                    num++;
                }
            }
            if(num>maxcolornum){
                maxcolornum=num;
            }
            num=0;
        }
        if(maxcolornum==5){
            maxnum=6;
        }
        //顺子
        //先排序
        const n = useCard.length;
        // 外层循环：控制排序的轮数（需要 n-1 轮）
        for (let i = 0; i < n - 1; i++) {
            // 内层循环：每轮比较相邻元素
            for (let j = 0; j < n - 1 - i; j++) {
                // 如果前一个元素大于后一个元素，则交换它们
                if (useCard[j].point > useCard[j + 1].point) {
                    //[handCard[j].node.x, handCard[j + 1].node.x] = [handCard[j + 1].node.x, handCard[j].node.x];
                    [useCard[j], useCard[j + 1]] = [useCard[j + 1], useCard[j]];
                }
            }
        }
        //比较大小
        let dvalue=0;
        for (let i = 0; i < n - 1; i++) {
            if(i+1>n-1){
                break;
            }
            if((useCard[i+1].point-useCard[i].point)==1){
                dvalue+=1;
            }
        }
        if(dvalue==4){
            //判断是不是同花顺
            if(maxnum==6){
                maxnum=8;
            }
            else{
            maxnum=7;
            }
        }
        let patternType={
            1:"highcard",
            2:"couple",
            3:"threecouple",
            4:"fourcouple",
            5:"fivecouple",
            6:"flush",
            7:"straight",
            8:"straightflush",
            9:"twopair",
            10:"fullhouse"
        }
        let patternName=patternType[maxnum];
        this.cardPair=patternName;
        return cardPatternsType[patternName];
        //console.log(maxnum);
    }
    //出牌
    PlayCard(handCard:Card[]){
        //出牌数减一
        this.SendMsg("modfiyPlay","PlayNumAndDisNum");
        let n = handCard.length;
        //存储牌位置
        let pos: number[] = [];
        for (let i = 0; i <= handCard.length - 1; i++) {
            pos.push(handCard[i].node.x);
        }
        for (let i = handCard.length - 1; i >= 0; i--) {
            if (handCard[i].istouch) {
                //将istouch取消方便下次重启使用
                handCard[i].istouch=false;
                // 加入弃牌堆
                this.upCards.push(handCard[i]);
                //进入出牌数组
                this.useCard.push(handCard[i]);
                // 从手牌中移除
                let card = handCard[i];
                handCard.splice(i, 1);
                //card.node.destroy();
                card.node.active = false;
                card.node.parent = this.node.parent.getChildByName("CardDeck");
                card.node.setPosition(0,0); // 移回牌堆
            }
        }
        //重新换位
        for (let i = 0; i <= handCard.length - 1; i++) {
            tween(handCard[i].node)
                .to(0.2, { x: pos[i] })
                .start();
        }
        //补牌
        this.DrawCard(n - handCard.length);
        //计分
        this.score(this.useCard);
        //清空用于下次出牌
        this.useCard=[];
    }
    //弃牌
    foldCard(handCard:Card[]){
        //如果弃牌数为0,无法弃牌
        if(ModuleMgr.instance.getModuel<PlayNumAndDisNum>("PlayNumAndDisNum")._disnum<=0){
            return;
        }
        //弃牌数减一
        this.SendMsg("modfiyDis","PlayNumAndDisNum");
        let n = handCard.length;
        //存储牌位置
        let pos:number[]=[];
        for (let i = 0; i <= handCard.length - 1; i++) {
            pos.push(handCard[i].node.x);
        }
        for (let i = handCard.length - 1; i >= 0; i--) {
            if (handCard[i].istouch) {
                // 加入弃牌堆
                this.upCards.push(handCard[i]);
                // 从手牌中移除
                let card = handCard[i];
                handCard.splice(i, 1);
                card.node.active = false;
                card.node.parent = this.node.parent.getChildByName("CardDeck");
                card.node.setPosition(0,0); // 移回牌堆
            }
        }
        //重新换位
        for (let i = 0; i <= handCard.length - 1; i++) {
            tween(handCard[i].node)
            .to(0.2,{x:pos[i]})
            .start();
        }
        //补牌
        this.DrawCard(n - handCard.length);

    }
    //摸牌
    DrawCard(drawnum:number){
        let num:number=0;
        let Card=this.node.parent.getChildByName("Cards").getComponent(Cards).handCard;
        for(let i=0;i<=drawnum-1;i++){
            //如果卡组中数量不够摸了，退出循环
            if(this.cards.length<=i){
                break;
            }
            num=i;
            let card=this.cards[i];
            Card.push(card);
            //父节点变为手牌
            card.node.parent=this.node.parent.getChildByName("Cards");  
            card.node.active=true;
            card.node.setPosition(0,0,0);
            //位移量
            let distance=(drawnum-i)*110;
            tween(card.node)
            .by(0.3,{position:v3(-distance,0,0)})
            .call(()=>{            
                //console.log("摸了"+(i+1)+" "+card.node);
            })
            .start();

        }
        //将摸出的牌移除cards(牌堆)
        this.cards.splice(0,num+1);
        //将牌数传递给记牌器
        this.SendMsg("cardNumModify","Cardnum",num+1);
    }
    //加牌
    AddCard(points:number,colorType:colorType,effectType?:effectType,isback:boolean=true){
        let newcard=instantiate(this.card);
        let newcardts=newcard.getComponent(Card);
        newcardts.init(points,colorType,effectType);
        //是否放入抽牌堆
        if(isback){
            this.cards.push(newcardts);
            let carddeck = this.node.parent.getChildByName("CardDeck");
            newcard.parent = carddeck;
            newcard.active = false;
            newcardts.istouch=false;
        }
        return newcardts;
    }
    // 造牌 - 随机生成4张卡牌供选择
    CreateCard(upLayer:Node,cardnum: number = 4): Card[] {
        const generatedCards: Card[] = [];
        //因为Shop中update调用Cards节点，而加牌没有将Game的Cards放入Shop中，所以创建一个Cards存储新牌
        let Cards = new Node("Cards");
        Cards.parent = upLayer;
        for (let i = 0; i < cardnum; i++) {
            // 随机生成卡牌属性
            const randomPoints = Math.floor(Math.random() * 13) + 1; // 1-13
            const randomColor = Math.floor(Math.random() * 4); // 0-3，假设有4种颜色
            // 创建卡牌
            const card = this.AddCard(randomPoints, randomColor,effectType.none,false);
            card.node.parent=Cards;
            //先将其与抽牌堆分开，选择好后放回
            
            generatedCards.push(card);
            // 激活卡牌并设置位置供玩家选择
            card.node.active = true;
            card.node.setPosition(-300+(200*i), card.node.parent.y-200, 0); // 水平排列
        }
        return generatedCards;
    }
    //删牌
    deleteCard(handCard:Card[],cards:Node){
        for (let i = handCard.length - 1; i >= 0; i--) {
            const cardComponent = handCard[i].getComponent(Card);
            if (cardComponent && cardComponent.istouch) {
                // 销毁节点并从数组中移除
                this.cardnum-=1;
                handCard[i].node.destroy();
                handCard.splice(i, 1);
            }
        }
        //回到牌堆
        for (let i = handCard.length - 1; i >= 0; i--) {
            tween(handCard[i].node)
                .to(0.2, { position: v3(450, handCard[i].node.y, 0) })
                .call(() => {
                    //缓动结束后回到Game中
                    if (i == 0) {
                        cards.parent = this.node.parent;
                        cards.setSiblingIndex(1);
                        for (let i = handCard.length - 1; i >= 0; i--){
                            handCard[i].istouch=false;
                        }
                    }
                })
                .start();
        }
    }
    //洗牌
    shakeout(){
        let cards = this.cards; // 您的卡牌数组
        let currentIndex = cards.length;
        let temporaryValue, randomIndex;
        // 当还有剩余元素未洗牌时
        while (currentIndex !== 0) {
            // 选取一个剩余元素
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex--;

            // 与当前元素交换
            temporaryValue = cards[currentIndex];
            cards[currentIndex] = cards[randomIndex];
            cards[randomIndex] = temporaryValue;
        }
        //根据洗牌后位置更改节点优先级
        for(let i=0;i<=cards.length-1;i++){
            cards[i].node.setSiblingIndex(i);
        }
        //let ct=cards.length;
        // for(let card of this.cards){
        //     card.test();
        // }
    }
}


